﻿'   Overlay.vb
'   WireBear Awesemulator
'
'   Created by Chris Kent
'   Copyright 2011 WireBear. All rights reserved
'
#Region "License Information"
'   WireBear Awesemulator is free software: you can redistribute it and/or modify
'   it under the terms of the GNU General Public License as published by
'   the Free Software Foundation, either version 3 of the License, or
'   (at your option) any later version.
'
'   WireBear Awesemulator is distributed in the hope that it will be useful,
'   but WITHOUT ANY WARRANTY; without even the implied warranty of
'   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'   GNU General Public License for more details.
'
'   You should have received a copy of the GNU General Public License
'   along with WireBear Awesemulator - License.txt
'   If not, see <http://www.gnu.org/licenses/>.
#End Region


Imports System.Runtime.InteropServices

Public Class Overlay

    Public Sub Overlay_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        UpdateFormDisplay()
    End Sub

    ''' <summary>
    ''' Overlay Setup
    ''' </summary>
    ''' <param name="Background">The image to use for the overlay</param>
    Public Sub SetBackgroundImage(ByVal Background As Bitmap)
        BackgroundImage = Background
        Size = Background.Size
        UpdateFormDisplay()
    End Sub

    Protected Overrides ReadOnly Property CreateParams As CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H80000 Or WS_EX.Transparent
            Return cp
        End Get
    End Property

    Public Sub UpdateFormDisplay()
        Dim screenDc As IntPtr = GetDC(IntPtr.Zero)
        Dim memDc As IntPtr = CreateCompatibleDC(screenDc)
        Dim hBitmap As IntPtr = IntPtr.Zero
        Dim oldBitmap As IntPtr = IntPtr.Zero
        Try
            'Display-image
            Using bmp As New Bitmap(BackgroundImage)
                hBitmap = bmp.GetHbitmap(Color.FromArgb(0))
                oldBitmap = SelectObject(memDc, hBitmap)
                'Display-rectangle
                Dim size As Size = bmp.Size
                Dim pointSource As New Point(0, 0)
                Dim topPos As New Point(Left, Top)
                'Set up blending options
                Dim blend As New BLENDFUNCTION() With {.BlendOp = AC_SRC_OVER, .BlendFlags = 0, .SourceConstantAlpha = 255, .AlphaFormat = AC_SRC_ALPHA}
                UpdateLayeredWindow(Handle, screenDc, topPos, size, memDc, pointSource, 0, blend, ULW_ALPHA)
                'Clean-up
                ReleaseDC(IntPtr.Zero, screenDc)
                If hBitmap <> IntPtr.Zero Then
                    SelectObject(memDc, oldBitmap)
                    DeleteObject(hBitmap)
                End If
            End Using
            DeleteDC(memDc)
        Catch
            'Do Nothing
        End Try
    End Sub

#Region "PINVOKE Functions"

    Public Enum GWL As Integer
        ExStyle = -20
    End Enum

    Public Enum WS_EX As Integer
        Transparent = &H20
        Layered = &H80000
    End Enum

    Public Enum LWA As Integer
        ColorKey = &H1
        Alpha = &H2
    End Enum

    <DllImport("user32.dll", EntryPoint:="GetWindowLong")> _
    Public Shared Function GetWindowLong( _
        ByVal hWnd As IntPtr, _
        ByVal nIndex As GWL _
            ) As Integer
    End Function

    <DllImport("user32.dll", EntryPoint:="SetWindowLong")> _
    Public Shared Function SetWindowLong( _
        ByVal hWnd As IntPtr, _
        ByVal nIndex As GWL, _
        ByVal dwNewLong As WS_EX _
            ) As Integer
    End Function

    <DllImport("user32.dll", EntryPoint:="SetLayeredWindowAttributes")> _
    Public Shared Function SetLayeredWindowAttributes( _
        ByVal hWnd As IntPtr, _
        ByVal crKey As Integer, _
        ByVal alpha As Byte, _
        ByVal dwFlags As LWA _
            ) As Boolean
    End Function

    Public Const AC_SRC_OVER As Byte = &H0
    Public Const AC_SRC_ALPHA As Byte = &H1
    Public Const ULW_ALPHA As Int32 = &H2

    <DllImport("user32.dll")> _
    Private Shared Function GetDC(ByVal hwnd As IntPtr) As IntPtr
    End Function

    <StructLayout(LayoutKind.Sequential, Pack:=1)> _
    Public Structure BLENDFUNCTION
        Public BlendOp As Byte
        Public BlendFlags As Byte
        Public SourceConstantAlpha As Byte
        Public AlphaFormat As Byte
    End Structure

    <DllImport("user32.dll", ExactSpelling:=True, SetLastError:=True)> _
    Public Shared Function UpdateLayeredWindow(ByVal hwnd As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, ByVal hdcSrc As IntPtr, ByRef pprSrc As Point, ByVal crKey As Int32, ByRef pblend As BLENDFUNCTION, ByVal dwFlags As Int32) As Boolean
    End Function

    <DllImport("gdi32.dll", SetLastError:=True)> _
    Public Shared Function CreateCompatibleDC(ByVal hRefDC As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Boolean
    End Function

    <DllImport("gdi32.dll")> _
    Public Shared Function DeleteDC(ByVal hdc As IntPtr) As Boolean
    End Function

    <DllImport("gdi32.dll")> _
    Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
    End Function

    <DllImport("Gdi32.dll")> _
    Public Shared Function SelectObject(ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
    End Function

#End Region

End Class
